<script setup lang="ts">
import { onMounted, PropType, ref, watch } from 'vue'
import { fabric } from 'fabric'
import { IMeasure, TShape } from '@renderer/views/imgViewer/components/types'
import { useDrawMeasuring } from '@renderer/views/imgViewer/components/newMeasureHelper'

let measuringMap: Map<string, any> = new Map()
let measureDoneMap: Map<string, any> = new Map()

const canvasRef = ref<any>(null)
const props = defineProps({
  measureInfo: {
    type: Object as PropType<IMeasure>,
    default: () => {
      return {
        measuringArr: [],
        measureDoneArr: []
      }
    }
  }
})

let canvas: any
let measure: any

onMounted(() => {
  const updateMeasureLayer = (newMeasureInfo: IMeasure) => {
    console.log('updateMeasureLayer')
    getMeasuredLines(newMeasureInfo)
    getMeasuringLines(newMeasureInfo)
    canvas.renderAll()
  }

  const getMeasuredLines = (newMeasureInfo: IMeasure) => {
    const measureDoneArr = newMeasureInfo.measureDoneArr
    for (const oneMeasure of measureDoneArr) {
      const { type, id } = oneMeasure
      const {
        lines, controls
      } = getOneMeasureAllLines(oneMeasure, true, measureDoneMap)
      if (!measureDoneMap.has(id)) {
        canvas.add(...lines)
        canvas.add(...controls)
        measureDoneMap.set(id, {
          type,
          lines,
          controls
        })
      }
    }
  }

  const getMeasuringLines = (newMeasureInfo: IMeasure) => {
    const measuringArr = newMeasureInfo.measuringArr
    for (const oneMeasure of measuringArr) {
      const { type, id } = oneMeasure
      const {
        lines, controls
      } = getOneMeasureAllLines(oneMeasure, false, measureDoneMap)
      if (!measuringMap.has(id)) {
        canvas.add(...lines)
        canvas.add(...controls)
        measuringMap.set(id, {
          type,
          lines,
          controls
        })
      }
    }
  }

  const updateLocation = (id: string, newPoints: any[], map: Map<string, any>) => {
    const {
      lines,
      controls
    } = map.get(id)
    controls.map((control, index) => {
      control.set({
        left: newPoints[index][0],
        top: newPoints[index][1]
      })
      if (index > 0) {
        const startPoint = newPoints[index - 1]
        const endPoint = newPoints[index]
        const line = lines[index - 1]
        line.set({
          x1: startPoint.x,
          y1: startPoint.y,
          x2: endPoint.x,
          y2: endPoint.y
        })
      }
    })
    return {
      lines,
      controls
    }
  }

  // 得到一个测量记录的所有线段和控制点。如果id已经存在就更新坐标，如果id不存在则创建元素。
  const getOneMeasureAllLines = (oneMeasure: TShape, finishFlag: boolean, map: Map<string, any>) => {
    const {
      type, id, points
    } = oneMeasure
    if (map.has(id)) {
      const { lines, controls } = updateLocation(id, points, map)
      return {
        lines: lines,
        controls: controls
      }
    } else {
      let controls: any[] = []
      let lines: any[] = []
      points.map((item, index) => {
        if (!finishFlag) {
          const options: any = {
            left: item[0],
            top: item[1],
            strokeWidth: 2,
            radius: 5,
            fill: '#fff',
            stroke: '#666',
            originX: 'center', // x轴方向以中心点为原点
            originY: 'center', // y轴方向以中心点为原点
            hasControls: false, // 不显示控制器
            hasBorders: false, // 不显示控制器的边
            cid: `circle-${index}`, // 自定义属性
            lockRotation: true
          }
          controls.push(new fabric.Circle(options))
        }
        if (index > 0) {
          const startPoint = points[index - 1]
          const endPoint = points[index]
          const line = new fabric.Line([startPoint[0], startPoint[1], endPoint[0], endPoint[1]], {
            stroke: 'yellow',
            selectable: false
          })
          lines.push(line)
        }
      })
      return {
        lines: lines,
        controls: controls
      }
    }
  }
  const init = () => {
    const { width, height } = canvasRef.value.getBoundingClientRect()
    canvasRef.value.width = width
    canvasRef.value.height = height
    canvas = new fabric.Canvas(canvasRef.value, {
      selection: false
    })
    // measure = useDrawMeasuring(canvas)
    measure = useDrawMeasuring(canvas)
  }
  init()
  // watch(() => props.measureInfo, (newMeasureInfo) => {
  //   updateMeasureLayer(newMeasureInfo)
  // })

})
</script>

<template>
  <div ref="containerRef"
       class="w-full h-full absolute left-0 top-0 z-10">
    <canvas ref="canvasRef" class="w-full h-full"></canvas>
  </div>
</template>


<style scoped>

</style>
